package com.terrier.ui.containers
{
    import com.terrier.ui.controls.WxHScrollBar;
    import com.terrier.ui.controls.WxPanel;
    import com.terrier.ui.controls.WxScrollPolicy;
    import com.terrier.ui.controls.WxVScrollBar;
    import com.terrier.ui.events.WxRangeEvent;
    import com.terrier.ui.skins.IWxScrollPanelSkin;
    import com.terrier.ui.skins.WxSkinManager;

    import flash.geom.Rectangle;

    /**
     * 带有滚动条的面板
     * @author Jarvis.weng
     */
    public class WxScrollPanel extends WxPanel
    {
        /**
         * @private
         */
        protected var _hScrollBar:WxHScrollBar;

        /**
         * @private
         */
        protected var _vScrollBar:WxVScrollBar;

        private var _adjustSize:Number = 0;

        private var _vScrollPolicy:String = WxScrollPolicy.AUTO;

        private var _hScrollPolicy:String = WxScrollPolicy.AUTO;

        /**
         * 构造函数
         */
        public function WxScrollPanel()
        {
            super();

            _contentPane.clipping = true;
        }

        /**
         * @private
         */
        override public function setSkinID(skinID:String):void
        {
            setSkin(WxSkinManager.getScrollPanelSkin(skinID));
        }

        /**
         * 水平滚动条的出现模式, 分别是打开, 关闭, 自动.
         * 处于打开模式时, 水平滚动条将始终出现. (设置为<code>WxScrollPolicy.ON</code>)
         * 处于关闭模式时, 水平滚动条将始终关闭. (设置为<code>WxScrollPolicy.OFF</code>)
         * 处于自动模式时, 水平滚动条将在需要的时候自动出现或自动关闭. (设置为<code>WxScrollPolicy.AUTO</code>)
         * @see WxScrollPolicy
         * @return
         */
        public function get hScrollPolicy():String
        {
            return _hScrollPolicy;
        }

        /**
         * @private
         */
        public function set hScrollPolicy(value:String):void
        {
            if (value == _hScrollPolicy)
            {
                return;
            }

            _hScrollPolicy = value;

            invalidateLayout();
        }

        /**
         * 垂直滚动条的出现模式, 分别是打开, 关闭, 自动.
         * 处于打开模式时, 垂直滚动条将始终出现. (设置为<code>WxScrollPolicy.ON</code>)
         * 处于关闭模式时, 垂直滚动条将始终关闭. (设置为<code>WxScrollPolicy.OFF</code>)
         * 处于自动模式时, 垂直滚动条将在需要的时候自动出现或自动关闭. (设置为<code>WxScrollPolicy.AUTO</code>)
         * @see WxScrollPolicy
         * @return
         */
        public function get vScrollPolicy():String
        {
            return _vScrollPolicy;
        }

        /**
         * @private
         */
        public function set vScrollPolicy(value:String):void
        {
            if (value == _vScrollPolicy)
            {
                return;
            }

            _vScrollPolicy = value;

            invalidateLayout();
        }

        /**
         * @private
         */
        override protected function updateLayout():void
        {
            super.updateLayout();

            if (skin == null)
            {
                return;
            }

            var bound:Rectangle = _contentPane.childrenBound;
            var paneBound:Rectangle = contentPaneBound;

            _contentPane.x = paneBound.x;
            _contentPane.y = paneBound.y;

            _contentPane.width = _adjustSize > 0 ? paneBound.width - _adjustSize : paneBound.width;
            _adjustSize = enableHScrollBar(bound.width > _contentPane.width);

            _contentPane.height = _adjustSize > 0 ? paneBound.height - _adjustSize : paneBound.height;
            _adjustSize = enableVScrollBar(bound.height > _contentPane.height);

            if (_adjustSize > 0)
            {
                _contentPane.width = _width - _adjustSize;
                if (_hScrollBar == null)
                {
                    enableHScrollBar(bound.width > _contentPane.width);
                }
            }

            layoutHScrollBar(bound);
            layoutVScrollBar(bound);
        }

        /**
         * @private
         */
        protected function get contentPaneBound():Rectangle
        {
            return new Rectangle(0, 0, _width, _height);
        }

        private function enableHScrollBar(enabled:Boolean):Number
        {
            var scrollBarSize:Number = 0;

            if ((enabled && hScrollPolicy == WxScrollPolicy.AUTO) || hScrollPolicy == WxScrollPolicy.ON)
            {
                if (_hScrollBar == null)
                {
                    _hScrollBar = new WxHScrollBar();
                    _hScrollBar.setSkin(skin.hScrollBarSkin);
                    addChild(_hScrollBar);
                    _hScrollBar.addEventListener(WxRangeEvent.VALUE_CHANGE, hScrollChangeHandler);
                }
                scrollBarSize = _hScrollBar.height;
            }
            else
            {
                if (_hScrollBar != null)
                {
                    _hScrollBar.removeEventListener(WxRangeEvent.VALUE_CHANGE, hScrollChangeHandler);
                    removeChild(_hScrollBar);
                    _hScrollBar = null;
                }
            }

            return scrollBarSize
        }

        private function enableVScrollBar(enabled:Boolean):Number
        {
            var scrollBarSize:Number = 0;

            if ((enabled && vScrollPolicy == WxScrollPolicy.AUTO) || vScrollPolicy == WxScrollPolicy.ON)
            {
                if (_vScrollBar == null)
                {
                    _vScrollBar = new WxVScrollBar();
                    _vScrollBar.setSkin(skin.vScrollBarSkin);
                    addChild(_vScrollBar);
                    _vScrollBar.addEventListener(WxRangeEvent.VALUE_CHANGE, vScrollChangeHandler);
                }
                scrollBarSize = _vScrollBar.width;
            }
            else
            {
                if (_vScrollBar != null)
                {
                    _vScrollBar.removeEventListener(WxRangeEvent.VALUE_CHANGE, vScrollChangeHandler);
                    removeChild(_vScrollBar);
                    _vScrollBar = null;
                }
            }

            return scrollBarSize;
        }

        private function layoutHScrollBar(bound:Rectangle):void
        {
            if (_hScrollBar == null)
            {
                return;
            }

            _hScrollBar.x = _contentPane.x;
            _hScrollBar.y = _contentPane.y + _contentPane.height;
            _hScrollBar.width = _contentPane.width;

            _hScrollBar.pageSize = _contentPane.width;
            _hScrollBar.maximum = bound.right - _hScrollBar.pageSize;
            _hScrollBar.minimum = bound.left;
            _hScrollBar.value = _contentPane.scrollX - _hScrollBar.minimum;

            _contentPane.scrollX = _hScrollBar.value;
        }

        private function layoutVScrollBar(bound:Rectangle):void
        {
            if (_vScrollBar == null)
            {
                return;
            }

            _vScrollBar.x = _contentPane.x + _contentPane.width;
            _vScrollBar.y = _contentPane.y;
            _vScrollBar.height = _contentPane.height;

            _vScrollBar.pageSize = _contentPane.height;
            _vScrollBar.maximum = bound.bottom - _vScrollBar.pageSize;
            _vScrollBar.minimum = bound.top;
            _vScrollBar.value = _contentPane.scrollY - _vScrollBar.minimum;

            _contentPane.scrollY = _vScrollBar.value;
        }

        private function hScrollChangeHandler(e:WxRangeEvent):void
        {
            _contentPane.scrollX = _hScrollBar.value;
        }

        private function vScrollChangeHandler(e:WxRangeEvent):void
        {
            _contentPane.scrollY = _vScrollBar.value;
        }

        private function get skin():IWxScrollPanelSkin
        {
            return _skin as IWxScrollPanelSkin;
        }
    }
}
